<template>
  <div :id="`wft-advanced-container-${curComp.id}`" @dblclick.stop="containerDblclick" @contextmenu="advancedContainerContextHandler" :class="['wft-advanced-container', { 'wft-container-glowing': curComp.config.isEnchase }]">
    <DynamicComp
      v-for="comp in curComp.children"
      :key="comp.id"
      ref="dynamicDraggableChildListRef"
      :cur-comp="comp"
      :panel-json="panelJson"
      :isConflictCheck="isConflictCheck"
      :style="{ 'pointer-events': curComp.config.isEnchase ? 'auto' : 'none' }"
      @getRefLineParams="getRefLineParams"
      @onActivated="curComp => $emit('onActivated', curComp)"
      @compContext="(e, curComp) => $emit('compContext', e, curComp)"
    />
    <!--辅助线-->
    <span class="ref-line v-line"
      v-for="item in vLine"
      v-show="item.display"
      :key="item.id"
      :style="{ left: item.position, top: item.origin, height: item.lineLength }"
    />
    <span class="ref-line h-line"
      v-for="item in hLine"
      v-show="item.display"
      :key="item.id"
      :style="{ top: item.position, left: item.origin, width: item.lineLength }"
    />

    <!-- 画板右键 -->
    <AdvancedContainerContextPanel
      v-if="showAdvancedContainerPanelContext"
      v-bind="contextConfig"
      :cur-comp="curComp"
      :cur-copy-comp="curCopyComp"
      :id="`wft-advanced-container-${curComp.id}`"
    />

    <!-- 文字提示 -->
    <div class="wft-advanced-container-tip" v-show="!curComp.config.isEnchase && !curComp.children?.length">双击切换状态</div>
  </div>
</template>
<script setup lang="ts">
import DynamicComp from 'generator/index/Layout/WorkBench/Dynamic/index.vue'
import { getUuid } from 'wft-utils'
import AdvancedContainerContextPanel from './context.vue'
import Bus from '@/utils/bus'
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { compDefault, panelJsonDefault } from 'generator/index/Layout/ConfigPanel/widget/default'
import { DragEventEnum, DragKeyEnum } from '@/enums';
import { useMessage } from '@/hooks';

onMounted(() => {
  Bus.on('hideAdvancedContainerPanelContext', hideAdvancedContainerPanelContext)
  initParentSize()
})

onUnmounted(() => {
  Bus.off('hideAdvancedContainerPanelContext', hideAdvancedContainerPanelContext)
  if(timer) {
    clearTimeout(timer)
    timer = null
  }
})

const contextConfig = ref<{
  top: number | string,
  left: number | string,
  right: string | number,
  bottom: string| number
}>({
  top: 0,
  left: 0,
  right: 'none',
  bottom: 'none'
})
const showAdvancedContainerPanelContext = ref(false)
let timer: number | null = null
const vLine = ref<any[]>([])
const hLine = ref<any[]>([])
const dynamicDraggableChildListRef = ref<Array<InstanceType<typeof DynamicComp>>>()

const props = withDefaults(defineProps<{
  panelJson?: TPanel,
  curComp?: TComp,
  isConflictCheck?: boolean,
  curCopyComp?: TComp | null
}>(), {
  panelJson: () => panelJsonDefault,
  curComp: () => compDefault,
  isConflictCheck: false,
  curCopyComp: null
})

const emits = defineEmits<{
  (e: 'onActivated', curComp: TComp): void;
  (e: 'compContext', ...args: any[]): void;
}>()

watch(() => props.curComp.children, () => {
  nextTick(() => {
    if(timer) clearTimeout(timer)
    timer = setTimeout(() => {
      initParentSize()
    }, 200)
  })
}, { deep: true })

// 初始化父元素大小
function initParentSize() {
  if(dynamicDraggableChildListRef.value && dynamicDraggableChildListRef.value.length) {
    dynamicDraggableChildListRef.value.forEach(dynamicdr => {
      dynamicdr.checkParentSize()
    })
  }
}

// 容器右键
function advancedContainerContextHandler(event: MouseEvent) {
  if(props.curComp.config.isEnchase) {
    event.stopPropagation()
    event.preventDefault()
    hideAdvancedContainerPanelContext()
    initContextPosition(event)
    showAdvancedContainerPanelContext.value = true
  }
}

// 隐藏右键面板
function hideAdvancedContainerPanelContext() {
  showAdvancedContainerPanelContext.value = false
}

// 初始化右键面板位置
function initContextPosition(event: MouseEvent) {
  const { left, top } = document.getElementById(`wft-advanced-container-${props.curComp.id}`)!.getBoundingClientRect()
  contextConfig.value.top = event.clientY - top
  contextConfig.value.left = event.clientX - left
  contextConfig.value.right = 'none'
  contextConfig.value.bottom = 'none'
}

// 双击可以拖动进来
function containerDblclick() {
  props.curComp.config.isEnchase = !props.curComp.config.isEnchase
  props.curComp.config.draggable = !props.curComp.config.isEnchase
  props.curComp.config.resizable = !props.curComp.config.isEnchase
  if(props.curComp.config.isEnchase) {
    initParentSize()
    startEvent()
  } else {
    clearEvent()
  }
}

// 监听事件
function startEvent() {
  const advancedContainer = document.getElementById(`wft-advanced-container-${props.curComp.id}`)!
  advancedContainer.addEventListener(DragEventEnum.ON_DRAG_OVER, compDragover)
  advancedContainer.addEventListener(DragEventEnum.ON_DROP, compDrop)
}

// 清除事件
function clearEvent() {
  const advancedContainer = document.getElementById(`wft-advanced-container-${props.curComp.id}`)!
  advancedContainer.removeEventListener(DragEventEnum.ON_DRAG_OVER, compDragover)
  advancedContainer.removeEventListener(DragEventEnum.ON_DROP, compDrop)
}

function compDragover(e: DragEvent) {
  e.preventDefault()
}

// 松开拖拽组件
function compDrop(event: DragEvent) {
  if(!event.dataTransfer?.getData(DragKeyEnum.DRAG_DATA_KEY)) return
  const dragData = JSON.parse(event.dataTransfer.getData(DragKeyEnum.DRAG_DATA_KEY))
  if(dragData.curCom.type == 'advanced') {
    return useMessage().warning('容器组件不可再嵌套高级组件！')
  }
  if(dragData.curCom.type == 'inertia') {
    return useMessage().warning('容器中不可嵌套惰性控件！')
  }
  const curCom = JSON.parse(JSON.stringify(dragData.curCom)) as TComp
  curCom.id = getUuid()
  const advancedContainer = document.getElementById(`wft-advanced-container-${props.curComp.id}`)!
  const { left, top, width, height } = advancedContainer.getBoundingClientRect()
  curCom.style.grid.top = Math.floor(event.clientY - top - dragData.offsetY)
  curCom.style.grid.left = curCom.style.percent.width == '100%' ? 0 : Math.floor(event.clientX - left - dragData.offsetX)
  curCom.style.percent.top = ((curCom.style.grid.top / height) * 100).toFixed(0) + '%'
  curCom.style.percent.left = ((curCom.style.grid.left / width) * 100).toFixed(0) + '%'
  if(curCom.style.percent.width == '100%') {
    curCom.style.grid.width = parseInt(String(width))
  } else {
    curCom.style.percent.width = ((curCom.style.grid.width / width) * 100).toFixed(0) + '%'
  }
  curCom.style.percent.height = ((curCom.style.grid.height / height) * 100).toFixed(0) + '%'
  curCom.config.isActive = true
  curCom.parentId = props.curComp.id
  curCom.parentKey = props.curComp.key
  props.curComp.children?.forEach(item => item.config.isActive = false)
  props.curComp.children?.push(curCom)
  emits('onActivated', curCom)
  Bus.emit('addStack')
  Bus.emit('startEventKeydown')
  if(event.dataTransfer?.getData(DragKeyEnum.DRAG_DATA_KEY)) {
    event.dataTransfer.clearData(DragKeyEnum.DRAG_DATA_KEY)
  }
}

// 辅助线回调事件
function getRefLineParams (params: any) {
  const { vLine: VL, hLine: HL } = params
  let id = 0
  vLine.value = VL.map((item: any) => {
    item['id'] = ++id
    return item
  })
  hLine.value = HL.map((item: any) => {
    item['id'] = ++id
    return item
  })
}
</script>
<style scoped>
.wft-advanced-container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.wft-advanced-container-tip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  color: #999;
}

.wft-container-glowing {
  box-shadow: 0 0 0 #d3e3fd, 0 0 10px #d3e3fd, 0 0 10px #d3e3fd, 0 0 30px #d3e3fd;
  cursor: auto;
}

.ref-line{
  position: absolute;
  background-color: rgba(8, 109, 109, .5);
  z-index: 9999;
}
.v-line{
  width: 1px;
}
.h-line{
  height: 1px;
}
</style>
